// #include<iostream>
// #include<pthread.h>
// #include<unistd.h>
// using namespace std;

// void* startRoutine(void* args)
// {
//     while(true)
//     {
//         cout << "线程正在运行" << endl;
//         sleep(1);
//     }
// }

// int main()
// {
//     pthread_t tid;
//     int n = pthread_create(&tid, nullptr, startRoutine, (void*)"thread1");
//     while(true)
//     {
//         cout << "main thread 正在运行" << endl;
//         sleep(1);
//     }

//     return 0;
// }


// #include<iostream>
// #include<pthread.h>
// #include<unistd.h>
// using namespace std;

// static void printTid(const char* name, const pthread_t& tid)
// {
//     printf("%s 正在运行, thread id: 0x%x\n", name, tid);
// }

// void* startRoutine(void* args)
// {
//     const char* name = static_cast<const char*>(args);
//     while(true)
//     {
//         printTid(name, pthread_self());
//         sleep(1);
//     }
// }

// int main()
// {
//     pthread_t tid;
//     int n = pthread_create(&tid, nullptr, startRoutine, (void*)"thread1");
//     while(true)
//     {
//         printTid("main thread", pthread_self());
//         sleep(1);
//     }

//     return 0;
// }

// #include<iostream>
// #include<pthread.h>
// #include<unistd.h>
// using namespace std;

// static void printTid(const char* name, const pthread_t& tid)
// {
//     printf("%s 正在运行, thread id: 0x%x\n", name, tid);
// }

// void* startRoutine(void* args)
// {
//     const char* name = static_cast<const char*>(args);
//     int cnt = 5;
//     while(true)
//     {
//         printTid(name, pthread_self());
//         sleep(1);
//         if(!(cnt--))
//             break;
//     }

//     cout << "线程退出啦..." << endl;
//     return nullptr;
// }

// int main()
// {
//     pthread_t tid;
//     int n = pthread_create(&tid, nullptr, startRoutine, (void*)"thread1");
//     sleep(10);
//     pthread_join(tid, nullptr);
//     cout << "main thread join success." << endl;
//     sleep(10);
//     while(true)
//     {
//         printTid("main thread", pthread_self());
//         sleep(1);
//     }

//     return 0;
// // }


// #include<iostream>
// #include<pthread.h>
// #include<unistd.h>
// using namespace std;

// void* thread_run(void* args)
// {
//     const char* name = static_cast<const char*>(args);
//     pthread_detach(pthread_self());//线程分离
//     cout << name << endl;
//     return nullptr;
// }

// int main()
// {
//     pthread_t tid;
//     int ret = pthread_create(&tid, nullptr, thread_run, (void*)"thread1 run");
//     if(ret != 0)
//     {
//         cout << "create success fail" << endl;
//         return 1;
//     }

//     int res = 0;

//     //很重要, 要让线程先分离,再等待
//     //如果不sleep,创建线程之后还没分离,主执行流就开始等待了,执行顺序是乱的(因为不止一个执行流了)
//     sleep(1);

//     if(pthread_join(tid, nullptr) == 0)
//     {
//         cout << "pthread wait success" << endl;
//         res = 0;
//     }
//     else
//     {
//         cout << "pthread wait fail" << endl;
//         res = 1;
//     }
//     return res;

// }



// // #include<iostream>
// // #include<pthread.h>
// // #include<unistd.h>
// // using namespace std;

// // int tickets = 10000;
// // pthread_mutex_t mutex;

// // void* route(void* args)
// // {
// //     const char* name = static_cast<const char*>(args);
// //     while(true)
// //     {
// //         pthread_mutex_lock(&mutex);
// //         if(tickets > 0)
// //         {
//             usleep(1000);
//             printf("%s sells tickets: %d\n", name, tickets);
//             tickets--;

//             pthread_mutex_unlock(&mutex);

//             usleep(1000);
//         }
//         else
//         {
//             pthread_mutex_unlock(&mutex);
//             break;
//         }
//     }
// }


// int main()
// {
//     pthread_t t1, t2, t3, t4;

//     pthread_mutex_init(&mutex, nullptr);

//     pthread_create(&t1, nullptr, route, (void*)"thread 1");
//     pthread_create(&t2, nullptr, route, (void*)"thread 2");
//     pthread_create(&t3, nullptr, route, (void*)"thread 3");
//     pthread_create(&t4, nullptr, route, (void*)"thread 4");

//     pthread_join(t1, nullptr);
//     pthread_join(t2, nullptr);
//     pthread_join(t3, nullptr);
//     pthread_join(t4, nullptr);

//     pthread_mutex_destroy(&mutex);

//     return 0;
// }


// #include<iostream>
// #include<cstdlib>
// #include<cstring>
// #include<pthread.h>
// #include<unistd.h>
// using namespace std;

// void* thread_run(void* args)
// {
//     pthread_detach(pthread_self());
//     cout << (char*)args << endl;
//     return nullptr;
// }

// int main()
// {
//     pthread_t tid;
//     if(pthread_create(&tid, nullptr, thread_run, (void*)"thread1 run...") != 0)
//     {
//         cerr << "create thread error" << endl;
//         return 1;
//     }

//     int ret = 0;
//     sleep(1);//很重要,要先让线程分离,再等待
//     //如果不sleep,创建线程之后还没分离,主执行流就开始等待了(执行顺序是乱的,不一定是一个执行流)
//     if(pthread_join(tid, nullptr) == 0)
//     {
//         cout << "pthread wait success" << endl;
//         ret = 0;
//     }
//     else
//     {
//         cerr << "pthread wait failed" << endl;
//         ret = 1;
//     }
//     cout << "ret = " << ret << endl;

//     return ret;
// }


#include<iostream>
#include<pthread.h>
#include<unistd.h>
using namespace std;

int ticket = 10000;
// pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;//这样定义初始化也可以,不用init()和destroy()了
pthread_mutex_t mutex;


void* route(void* args)
{
    char* id = (char*)args;
    while(1)
    {
        //只要对临界区加锁,而且加锁的粒度越细越好
        //加锁的本质是让线程执行临界区代码串行化
        //加锁是一套规范,通过临界区对临界资源进行访问的时候,要加锁都得加
        pthread_mutex_lock(&mutex);
        if(ticket > 0)
        {
            usleep(1000);
            cout << id << "sells ticket: " << ticket << endl;
            ticket--;
            pthread_mutex_unlock(&mutex);

            //other codes
            //模拟其他业务逻辑的执行
            usleep(1000);
        }
        else
        {
            pthread_mutex_unlock(&mutex);
            break;
        }
    }
}

int main()
{
    pthread_t t1, t2, t3, t4;

    pthread_mutex_init(&mutex, nullptr);

    pthread_create(&t1, nullptr, route, (void*)"thread 1");
    pthread_create(&t2, nullptr, route, (void*)"thread 2");
    pthread_create(&t3, nullptr, route, (void*)"thread 3");
    pthread_create(&t4, nullptr, route, (void*)"thread 4");

    pthread_join(t1, nullptr);
    pthread_join(t2, nullptr);
    pthread_join(t3, nullptr);
    pthread_join(t4, nullptr);

    pthread_mutex_destroy(&mutex);



    return 0;
}


#include<iostream>
#include<pthread.h>
#include<unistd.h>
using namespace std;

pthread_cond_t cond;
pthread_mutex_t mutex;

void* r1(void* args)
{
    while(1)
    {
        pthread_cond_wait(&cond, &mutex);//等待条件满足
        cout << "活动" << endl;
    }
}

void* r2(void* args)
{
    while(1)
    {
        pthread_cond_signal(&cond);//唤醒等待
        sleep(1);
    }
}

int main()
{
    pthread_t t1, t2;

    pthread_cond_init(&cond, nullptr);
    pthread_mutex_init(&mutex, nullptr);

    pthread_create(&t1, nullptr, r1, nullptr);
    pthread_create(&t2, nullptr, r2, nullptr);

    pthread_join(t1, nullptr);
    pthread_join(t2, nullptr);


    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);

    return 0;
}

